package pnca;


import MASS.*;                  // MASS Library
import java.io.IOException;
import java.util.*;             // Vectors, etc.
import java.util.AbstractMap.*; // for simple key-value pairs
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @name EnvironmentalAdapter creates MASS computing nodes
 *
 * @author Niko Simonson (Primary)
 * @author Brett Yasutake (Contributing)
 */
public class EnvironmentalAdapter extends Place {

    
    public final int ENVIRONMENTHANDLE = 0;
    public final int init_ = 0;         // initialize Places
    public final int readData_ = 1;
    public final int revealData_ = 2;
    public Places environment;
    public static double[][][][] data;
    public static int[] coordinates;
    public static int dimensionSize;
    public Object[] fixer;

    public EnvironmentalAdapter() {

    }

    public Object callMethod(int funcId, Object args) {
        switch (funcId) {
            case init_:
                return init(args);
            case readData_:
                return readData(args);
            case revealData_:
                return revealData(args);
        }
        return null;
    }

    public Object init(Object args) {
        coordinates = index;

        return (Object) null;
    }

    /**
     * @name readData - Read wind magnitudes and directions from NetCDF file
     * @param args - Not used
     * @return unused
     */
    public Object readData(Object args) {
        Object[] arguments = (Object[]) args;
        String fileName = arguments[0].toString();
        String[] vars = new String[arguments.length - 1];

        for (int i = 1; i < arguments.length; ++i) {
            vars[i - 1] = arguments[i].toString();
        }
        
        if( vars.length > 1) dimensionSize++;
        
        
       
        try {
            // Retreive input values from input adapter
            switch (dimensionSize) {
                case 2:
                    data[0][0] = InputAdapter.read2DFloat(fileName, vars[0], coordinates[0], coordinates[1]);
                case 3:
                    data[0] = InputAdapter.read2DFloats(fileName, vars, coordinates[0], coordinates[1]);
                case 4:
                    data = InputAdapter.read3DFloats(fileName, vars, coordinates[0], coordinates[1], coordinates[2]);
            }
        } catch (Exception ex) {
            Logger.getLogger(EnvironmentalAdapter.class.getName()).log(Level.SEVERE, null, ex);
        }

        
        // Check if values were retreived
        if (data == null) {
            System.err.println("Null input adapter return");
        }
        return (Object) null;
    }

    public double[][][][] revealData(Object args) {
        return data;
    }
    
    public void initialize(String[] massArgs, int procs, int threads, StatusAdapter status, int[] dataRanges, int... size) {
        try {
            int count = 1;

            dimensionSize = dataRanges.length;
            int[] values = new int[4];
            for (int i = 0; i < 4; ++i) {
                if (i >= dataRanges.length) {
                    values[i] = 1;
                } else {
                    values[i] = dataRanges[i];
                }
            }

            data = new double[values[0]][values[1]][values[2]][values[3]];

            for (int i = 0; i < size.length; ++i) {
                count *= size[i];
            }

            // Dummy object required by MASS
            fixer = new Object[count];

            // Start MASS
            status.reportMessage("Starting MASS");
            MASS.init(massArgs, procs, threads);


            environment = new Places(ENVIRONMENTHANDLE, "EnvironmentAdapter", null, size);
            status.reportMessage("Computational Nodes created");

            // Initialize all computing nodes
            environment.callAll(init_, fixer);
            status.reportMessage("Computational Nodes initialized");
        } catch (Exception ex) {
            Logger.getLogger(pnca.analytics.WindDivergence.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
